home *** CD-ROM | disk | FTP | other *** search
/ Packard Bell - Internet on a CD / internet on a cd.cdr / Internet / sites / Clementine_NASA / clemdsrc.hqx / clemdcmp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-07  |  17.6 KB  |  537 lines

  1. /*************************************************************************     
  2. *                   ----------------
  3. *                   |  CLEMDCMP    |
  4. *                   ----------------
  5. *
  6. *_TITLE CLEMDCMP Decompress clementine image into various formats
  7. *_DESC  CLEMDCMP will decompress a clementine image and format it into 
  8. *       one of four possible formats:
  9. *       1) decompressed pds image file, with pds labels, the historgram
  10. *           object, and an image object, either the browse image or
  11. *           the full image
  12. *       2) decompressed image file, no labels
  13. *       3) decompressed gif image
  14. *       4) decompressed tiff image
  15. *       This version is specifically for the Macintosh environment
  16. *
  17. *_HIST  Apr 07 1994  Tracie Sucharski, USGS, Flagstaff Original Version
  18. *       Aug 11 1994  Tracie Sucharski,  Added Apple menus and memory
  19. *                      handling
  20. *
  21. **************************************************************************/
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26.  
  27. #include "pds.h"
  28.  
  29. #define MM_TYPE 0x4D4D
  30. #define II_TYPE 0x4949
  31.  
  32. #define version "24-Aug-94"      /* version date of program */
  33.  
  34. struct {
  35.     char prgnam[9];               /* Program name */
  36.     char hlpfil[13];              /* Help file name */
  37.     char infile[128];             /* Input file name */
  38.     char outfile[128];            /* Output file name */
  39.     char img;                     /* Output image or browse image */
  40.     char format;                  /* Output file format */
  41.     } clemargs;
  42.  
  43.   long int resnumq = 420;
  44.   long int resnum = 400;
  45.  
  46.  
  47. main()
  48. {
  49.   char errbuf[132];
  50.   long lines;                    /* Number of lines and sample of image */
  51.   long samps;
  52.   int  i;                       
  53.   FILE *fpi, *fpo;               /* Input and output file pointers */
  54.   int ret;                       /* Return code */
  55.   char b[2];
  56.   short int *j;
  57.   char bitord;
  58.   
  59.   CursHandle hcur;
  60.   
  61.   PDSINFO *p;
  62.  
  63.   int labmod(char *text, char img, char bitord);
  64.   int writetif(FILE *fp, long nl, long ns, CHARH *buf, char bitord);
  65.  
  66.   void macinit();
  67.   void errmsg();
  68.   void clemdcmp_menu(); 
  69.   
  70.  
  71. /*************************************************************************
  72. *  Initialize the toolbox
  73. *************************************************************************/
  74.   macinit();
  75.     
  76. /*************************************************************************
  77. *  Initialize input variables
  78. *************************************************************************/
  79.   strcpy(clemargs.prgnam,"Clemdcmp");
  80.   strcpy(clemargs.hlpfil,"clemdcmp.hlp");
  81.   strcpy(clemargs.outfile," ");
  82.   clemargs.img = 'i';
  83.   clemargs.format = 'n';
  84.     
  85. /*************************************************************************
  86. *  Get input parameters
  87. *************************************************************************/
  88.   clemdcmp_menu("NEW");
  89.   
  90. /************************************************************************
  91. *  Determine the bit order
  92. ************************************************************************/
  93.  
  94.   j = (short int *) b;
  95.   b[0] = 1;
  96.   b[1] = 0;
  97.   if (*j == 1) bitord = 'l';
  98.   else bitord = 'm';
  99.  
  100. /***************************************************************************
  101. *  The following call will open the compressed Clementine image and create
  102. *  a structure containing the file objects.
  103. ****************************************************************************/
  104.   hcur = GetCursor(4);
  105.   if (hcur) SetCursor(*hcur);
  106.   p = PDSR(clemargs.infile, &lines, &samps);
  107.   if (p==NULL) {
  108.     errmsg("ERROR:CLEMDCMP-Error in decompression toolkit",&resnumq);
  109.     clemdcmp_menu("OLD");
  110.     exit;
  111.   }
  112.  
  113. /****************************************************************************
  114. *  If user chooses to output the full image, make sure it exists.
  115. ****************************************************************************/
  116.   if (clemargs.img == 'i' && !(p->image)) {
  117.     errmsg("ERROR:CLEMDCMP-This file does not contain a full image", &resnumq);
  118.     clemdcmp_menu("OLD");
  119.     exit;
  120.   }
  121. /****************************************************************************
  122. *  If user chooses to output the browse image, make sure it exists.
  123. ****************************************************************************/
  124.   if (clemargs.img == 'b' && !(p->brw_imag)) {
  125.     errmsg("ERROR:CLEMDCMP-This file does not contain a browse image",&resnumq);
  126.     clemdcmp_menu("OLD");
  127.     exit;
  128.   }
  129.  
  130. /******************************************************************************
  131. *  Open output file
  132. ******************************************************************************/
  133.   fpo = fopen(clemargs.outfile, "wb");
  134.  
  135. /*****************************************************************************
  136. *  For the pds formatted option, the labels will need to be modified before 
  137. *  writing out.  The uncompressed output file will either be the image or 
  138. *  the browse image, so the pointer to the browse image will be deleted, 
  139. *  and the image pointer will be modified to point to the start of the data.  
  140. *  The pointer to the histogram will also need to be modified.  The 
  141. *  ENCODING_COMPRESSION_RATIO will no longer be applicable, so the value is 
  142. *  changed to "N/A". 
  143. ******************************************************************************/
  144.   if (clemargs.format == 'p') {
  145.     if (labmod(p->text, clemargs.img, bitord) < 0) {
  146.       errmsg("ERROR:CLEMDCMP-Error reformatting labels",&resnumq);
  147.       clemdcmp_menu("OLD");
  148.       exit;
  149.     }
  150.     fwrite(p->text, strlen(p->text), 1, fpo);
  151.   }
  152.  
  153.   if (clemargs.format == 'p' || clemargs.format == 'n') {
  154. /*****************************************************************************
  155. *  If writing a pds formatted file, write the histogram data followed by 
  156. *  the image data, either the browse image or the full image.  If writing
  157. *  an unlabeled raw image write out only the image data.
  158. *****************************************************************************/
  159.     if (p->hist == NULL && clemargs.format == 'p') {
  160.       errmsg("ERROR:CLEMDCMP-Histogram is empty",&resnumq);
  161.       clemdcmp_menu("OLD");
  162.       exit;
  163.     }
  164.     if (clemargs.format == 'p') fwrite(p->hist, sizeof(long), 256, fpo);
  165.     if (clemargs.img == 'i') {
  166.       HLock(p->image);
  167.       fwrite((CHARH *)*(p->image), lines*samps, 1, fpo);
  168.       HUnlock(p->image);
  169.       if (clemargs.format == 'n') {
  170.         InitCursor();
  171.           sprintf(errbuf, "The size of the raw image created is %ld lines by %ld samples \
  172.                  with no header or label data.",lines, samps);
  173.           errmsg(errbuf, &resnum);
  174.       }
  175.       
  176.     }    
  177.     
  178.     if (clemargs.img == 'b') {
  179.       HLock(p->brw_imag); 
  180.       fwrite((unsigned char *)*(p->brw_imag), p->browse_nrows*p->browse_ncols, 1, fpo);
  181.        HUnlock(p->brw_imag); 
  182.       if (clemargs.format == 'n') {
  183.         InitCursor();
  184.            sprintf(errbuf, "The size of the raw image created is %d lines by %d samples \
  185.                   with no header or label data.", p->browse_nrows, p->browse_ncols);
  186.           errmsg(errbuf, &resnum);
  187.       }
  188.  
  189.     }
  190.   }
  191.  
  192.  
  193.  
  194.   if (clemargs.img == 'b') {  /* Write browse image */
  195.     
  196.     if (clemargs.format == 't') { 
  197.      HLock(p->brw_imag); 
  198.     /*  if (writetif(fpo, p->browse_nrows, p->browse_ncols, p->brw_imag, bitord) < 0) {*/
  199.       if (writetif(fpo, p->browse_nrows, p->browse_ncols, (unsigned char *)*(p->brw_imag), bitord) < 0) {
  200.           errmsg("ERROR:CLEMDCMP-Error writing tiff format",&resnumq);
  201.           clemdcmp_menu("OLD");
  202.           exit;
  203.       }
  204.       HUnlock(p->brw_imag);
  205.     }
  206.  
  207.     if (clemargs.format == 'g') { 
  208.       if (writegif(fpo, (long)p->browse_nrows, (long)p->browse_ncols, p->brw_imag) < 0) {
  209.           errmsg("ERROR:CLEMDCMP-Error writing gif format",&resnumq);
  210.           clemdcmp_menu("OLD");
  211.           exit;
  212.       }
  213.     }
  214.    
  215.   }
  216.  
  217.   else  {  /* Write image */
  218.     
  219.     if (clemargs.format == 't')  {
  220.       HLock(p->image);
  221.       if (writetif(fpo, lines, samps, (CHARH *)*(p->image), bitord) < 0) {
  222.         errmsg("ERROR:CLEMDCMP-Error writing tiff format",&resnumq);
  223.         clemdcmp_menu("OLD");
  224.         exit;
  225.       }
  226.       HUnlock(p->image);
  227.     }
  228.  
  229.     if (clemargs.format == 'g') {
  230.       if (writegif(fpo, lines, samps, p->image) < 0) {
  231.         errmsg("ERROR:CLEMDCMP-Error writing gif format",&resnumq);
  232.         clemdcmp_menu("OLD");
  233.         exit;
  234.       }
  235.     }
  236.  
  237.   }    
  238.  
  239.  
  240.   fclose(fpo);
  241.   
  242.   InitCursor();
  243.   clemdcmp_menu("OLD");
  244.  
  245. }
  246.  
  247.  
  248.  
  249.  
  250.  
  251. int labmod(char *text, char img, char bitord)
  252. /*****************************************************************************
  253. *
  254. *_TITLE  LABMOD - modify the clementine label to reflect the decompression
  255. *
  256. *_ARGS    Type    Variable     I/O  Description
  257. *_PARM    char    *text;        I   Pointer to clementine label
  258. *_PARM    char    img           I   Image Type (Full image or browse image)
  259. *_PARM    char    bitord        I   Bit order of current machine
  260. *_PARM    int     *ret          O   Return code
  261. *                                   0 - OK
  262. *
  263. *_DESC  LABMOD will modify the clementine label to reflect the decompression,
  264. *       and the possible rearranging of the browse image and image object.
  265. *
  266. *_HIST  Apr 13 1994 Tracie Sucharski, USGS, Flagstaff Original Version
  267. *       Jun 27 1994 Tracie Sucharski,  Fixed bug when writing out the
  268. *                       browse image.
  269. *       Jul 14 1994 Tracie Sucharski,  Changed output value of ENCODING_
  270. *                       TYPE keyword.
  271. *       Aug 23 1994 Tracie Sucharski,  Added NOTE to image object if the
  272. *                       output image is the browse image, also correct
  273. *                       the DATA_TYPE keyword in the histogram object
  274. *                       to indicate the correct byte order.
  275. *
  276. ****************************************************************************/
  277. {
  278.     int lbllen;                     /* Length of incoming label */
  279.     int nlbllen;                    /* Length of outgoing label */
  280.     char *start, *end;              /* Index pointers */
  281.     char sdummy[80];
  282.     int nc;                         /* Number of characters */
  283.     char byte[4];                   /* Starting bytes of objects */
  284.     int hbyte;                      /* Starting byte of Image Historgram */
  285.     int ibyte;                      /* Starting byte of Image */
  286.     int bbyte;                      /* Starting byte of Browse Image */
  287.     int diff;                       /* Difference in bytes between input */
  288.                                     /* label and output label */
  289.     char labels[6000];              /* Temporary buffer to hold labels */
  290.  
  291.  
  292.     lbllen = strlen(text);
  293.  
  294.     start = strstr(text, "^IMAGE_HISTOGRAM ");
  295.     sscanf(start, "%s = %d", sdummy, &hbyte);
  296.  
  297.     start = strstr(text, "^IMAGE ");
  298.     sscanf(start, "%s = %d", sdummy, &ibyte);
  299.  
  300.     start = strstr(text, "^BROWSE_IMAGE ");
  301.     sscanf(start, "%s = %d", sdummy, &bbyte);
  302.  
  303. /****************************************************************************
  304. *  Get rid of pointer to browse image.
  305. ****************************************************************************/
  306.     end = strchr(start,'\n');
  307.     strcpy(start, end+1);
  308.  
  309. /***************************************************************************
  310. *  If browse image is being written, get rid of IMAGE object, rename
  311. *  BROWSE_IMAGE object to IMAGE and add a note to indicate the output
  312. *  image is the browse image.
  313. ***************************************************************************/
  314.     if (img == 'b') {
  315.       start = strstr(text, "OBJECT = IMAGE\n");
  316.       end = strstr(start, "END_OBJECT");
  317.       strcpy(start, end+11);
  318.  
  319.       start = strstr(text, " BROWSE_IMAGE");
  320.       end = strchr(start, '\n');
  321.       strncpy(labels, text, (start-text)+1);
  322.       *(labels+(start-text+1)) = '\0';
  323.       strcat(labels, "IMAGE");
  324.       strcat(labels, end);
  325.       strcpy(text, labels);
  326.  
  327.       end = strstr(start, "END_OBJECT");
  328.       strncpy(labels, text, (end-text)+1);
  329.       *(labels+(end-text)) = '\0';
  330.       strcat(labels, "  NOTE          = \"Averaged subsampled EDR image\"\n");
  331.       strcat(labels, end);
  332.       strcpy(text, labels);
  333.  
  334.     }
  335.  
  336. /***************************************************************************
  337. *  If writing IMAGE object change ENCODING_COMPRESSION_RATIO and
  338. *  ENCODING_TYPE keyvalues to "N/A", since the output file is uncompressed.
  339. ***************************************************************************/
  340.     if (img == 'i') {
  341.  
  342.       start = strstr(text, "ENCODING_TYPE ");
  343.       end = strchr(start, '\n');
  344.       strncpy(labels, text, (end-text)-1);
  345.       *(labels+(end-text-1)) = '\0';
  346.       strcat(labels, " DECOMPRESSED\"");
  347.       strcat(labels, end);
  348.       strcpy(text, labels);
  349.  
  350.       start = strstr(text, "ENCODING_COMPRESSION_RATIO ");
  351.       end = strchr(start, '\n');
  352.       strncpy(labels, text, (start-text)+29);
  353.       *(labels+(start-text+29)) = '\0';
  354.       strcat(labels, "\"N/A\"");
  355.       strcat(labels, end);
  356.       strcpy(text, labels);
  357.  
  358. /***************************************************************************
  359. *  Get rid of the BROWSE_IMAGE object.
  360. ***************************************************************************/
  361.       start = strstr(text, "OBJECT = BROWSE_IMAGE");
  362.       end = strstr(start, "END_OBJECT");
  363.       strcpy(start, end+11);
  364.     }
  365.     
  366. /****************************************************************************
  367. *  If the bitorder is MSB which is different from that in the label(LSB),
  368. *  change the label.
  369. ****************************************************************************/
  370.     if (bitord == 'm') {
  371.       start = strstr(text, "LSB_INTEGER");
  372.       *start = 'M';
  373.     }
  374.  
  375. /****************************************************************************
  376. *  Adjust the object pointers.
  377. ****************************************************************************/
  378.     nlbllen = strlen(text);
  379.     hbyte = nlbllen + 1;
  380.     ibyte = hbyte + 1024;
  381.  
  382. /*****************************************************************************
  383. *  Now that there are new pointer values, write them out to the labels.
  384. *****************************************************************************/
  385.     sprintf(byte, "%d", hbyte);
  386.     nc = strlen(byte);
  387.     start = strstr(text, "^IMAGE_HISTOGRAM ");
  388.     strncpy(start+19, byte, nc);
  389.  
  390.     sprintf(byte, "%d", ibyte);
  391.     nc = strlen(byte);
  392.     start = strstr(text, "^IMAGE ");
  393.     strncpy(start+19, byte, nc);
  394.  
  395.     return(0);
  396.  
  397. }
  398.  
  399.     
  400.  
  401. /*************************************************************************
  402. *                       ------------
  403. *                       | WRITETIF |
  404. *                       ------------
  405. *
  406. *_TITLE  WRITETIF  Writes decompressed Clementine data into TIF format
  407. *
  408. *_DESC   WRITETIF takes decompressed Clementine data and writes an 
  409. *        uncompressed TIF formatted image.
  410. *
  411. *_HIST   May 04 1994  Tracie Sucharski, USGS, Flagstaff Original Version
  412. *
  413. *************************************************************************/
  414. #define BLKSIZE 32768L
  415.  
  416. int writetif(FILE *fp, long nl, long ns, CHARH *buf, char bitord)
  417. {
  418.   unsigned int j, nblocks, rem; /* Added by Luis Perez 06/29/94 */
  419.  
  420.   int fputword(FILE *fp, short int n);
  421.   int fputlong(FILE *fp, long n);
  422.  
  423.  
  424. /********************************************************************
  425. *  Write out the TIF header
  426. ********************************************************************/
  427.   if (bitord == 'm')  fputword(fp, MM_TYPE);
  428.   if (bitord == 'l')  fputword(fp, II_TYPE);
  429.   fputword(fp,42);
  430.   fputlong(fp,8L);
  431.  
  432. /********************************************************************
  433. *  Construct the Image File Directory (IFD)
  434. ********************************************************************/
  435.   fputword(fp, 8);     /* Eight Tags */
  436.  
  437.   fputword(fp, 254);   /* NewSubfileType */
  438.   fputword(fp, 4);     /* Long */
  439.   fputlong(fp, 1L);
  440.   fputlong(fp, 0L);
  441.  
  442.   fputword(fp, 256);   /* ImageWidth */
  443.   fputword(fp, 3);     /* Short */
  444.   fputlong(fp, 1L);    
  445.   if (bitord == 'm')
  446.     fputlong(fp, ns*65536); /* Shift value into the two high order bytes */
  447.   if (bitord == 'l')
  448.     fputlong(fp, ns);
  449.  
  450.   fputword(fp, 257);   /* ImageLength */
  451.   fputword(fp, 3);     /* Short */
  452.   fputlong(fp, 1L);
  453.   if (bitord == 'm')
  454.     fputlong(fp, nl*65536);  /* Shift value into the two high order bytes */
  455.   if (bitord == 'l')
  456.     fputlong(fp, nl);
  457.  
  458.   fputword(fp, 258);   /* BitsPerSample */
  459.   fputword(fp, 3);     /* Short */
  460.   fputlong(fp, 1L);
  461.   if (bitord == 'm') 
  462.     fputlong(fp, 524288L); /* 8 Shifted into the two high order bytes */
  463.   if (bitord == 'l')
  464.     fputlong(fp, 8L);
  465.  
  466.   fputword(fp, 259);   /* Compression */
  467.   fputword(fp, 3);     /* Short */
  468.   fputlong(fp, 1L);
  469.   if (bitord == 'm')
  470.     fputlong(fp, 65536L);    /* No compression */
  471.   if (bitord == 'l')
  472.     fputlong(fp, 1L);
  473.  
  474.   fputword(fp, 262);   /* PhotometricInterpretation */
  475.   fputword(fp, 3);     /* Short */
  476.   fputlong(fp, 1L);
  477.   if (bitord == 'm')
  478.     fputlong(fp, 65536L);  /* 1 Shifted into the two high order bytes */
  479.   if (bitord == 'l')
  480.     fputlong(fp, 1L);
  481.  
  482.   fputword(fp, 273);   /* StripOffsets - Start of image data */
  483.   fputword(fp, 4);     /* Long */
  484.   fputlong(fp, 1L);
  485.   fputlong(fp, 110L);
  486.  
  487.   fputword(fp, 277);   /* SamplesPerPixel */
  488.   fputword(fp, 3);     /* Short */
  489.   fputlong(fp, 1L);
  490.   if (bitord == 'm')
  491.     fputlong(fp, 65536L);
  492.   if (bitord == 'l')
  493.     fputlong(fp, 1L);
  494.  
  495.   fputlong(fp, 0L);
  496.  
  497. /***********************************************************************
  498. *  Write image data
  499. ***********************************************************************/
  500.   /*!!!!!! BE CAREFUL HERE !!!!!!*/
  501.   /* The third argument in fwrite is of type size_t, which under Turbo C
  502.      becomes an unsigned short int (16 bit integer). This means you have
  503.      to write the image data out in blocks of 64K bytes or less (32K is a
  504.      good number).
  505.      Added by Luis Perez 06/29/94. */
  506. #ifdef __TURBOC__
  507.   nblocks = (nl*ns) / BLKSIZE;
  508.   rem = (nl*ns) % BLKSIZE;
  509.   for (j=0; j<nblocks; j++, buf+=BLKSIZE)
  510.     fwrite(buf,1,BLKSIZE,fp);
  511.   if ( rem > 0 )
  512.     fwrite(buf,1,rem,fp);
  513. #else
  514.   fwrite(buf, 1, nl*ns, fp);
  515. #endif
  516.  
  517.   return(0);
  518.  
  519. }
  520.  
  521.  
  522.  
  523.  
  524. int fputword(FILE *fp, short int n)
  525. {
  526.   fwrite(&n, 2, 1,fp);
  527.   
  528. }
  529.  
  530. int fputlong(FILE *fp, long n)
  531. {
  532.   fwrite(&n, 4, 1, fp);
  533.  
  534. }
  535.  
  536.